package com.yuqih.common.service;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Callable;

import org.apache.commons.beanutils.PropertyUtils;

import com.yuqih.common.exception.CodedException;
import com.yuqih.common.service.cache.CacheThreadContext;

public class ServiceHelper {
	
	/**
	 * 该方法中不要有数据库写操作，否则可能出现脏数据
	 * 
	 * @param callable
	 * @return
	 */
	public  static <T> T handleWithCache(Callable<T> callable) {
		CacheThreadContext.enable();
		try {
			return callable.call();
		} catch (Exception e) {
			throw CodedException.from(e);
		} finally {
			CacheThreadContext.disable();
		}
	}
	
	/**
	 * 子条目比较的方法
	 * 
	 * @param current
	 * @param original
	 * @param idField
	 * @param comparator
	 * @param toAddList
	 * @param toModifyList
	 * @param toRemoveList
	 */
	public static <T> void compareList(List<T> current, List<T> original, String idField, 
			IObjectComparator<T> comparator,
			List<T> toAddList, List<T> toModifyList, List<T> toRemoveList) {

		Map<Object, T> contentMap = new HashMap<Object, T>();
		for (T dto : current) {
			try {
				Object id = PropertyUtils.getProperty(dto, idField);
				if (id == null) {
					toAddList.add(dto);
					continue;
				}
				
				contentMap.put(id , dto);
			} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
				throw CodedException.from(e);
			}
		}

		Map<Object, T> originalMap = new HashMap<Object, T>();
		for (T dto : original) {
			try {
				originalMap.put(PropertyUtils.getProperty(dto, idField), dto);
			} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
				throw CodedException.from(e);
			}
		}

		for (Entry<Object, T> entry : contentMap.entrySet()) {
			
			T cachedDto = originalMap.get(entry.getKey());
			if (cachedDto == null) {
				// contentList中有cachedList中没有的 - 新增
				toAddList.add(entry.getValue());
			} else if (comparator == null) {
				// contentList中和cachedList中不一样的 - 修改
				toModifyList.add(entry.getValue());
			} else if (!comparator.equals(cachedDto, entry.getValue())) {
				// contentList中和cachedList中不一样的 - 修改
				toModifyList.add(entry.getValue());
			}
		}

		for (Entry<Object, T> entry : originalMap.entrySet()) {
			T dto = contentMap.get(entry.getKey());
			if (dto == null) {
				// contentList中没有cachedList中有的 - 删除
				toRemoveList.add(entry.getValue());
			}
		}

		
	}

}
